home *** CD-ROM | disk | FTP | other *** search
- Subject: v22i026: MIT Athena delete/undelete programs, release 2, Part02/03
- Newsgroups: comp.sources.unix
- Approved: rsalz@uunet.UU.NET
- X-Checksum-Snefru: 2b340523 8b02d9f9 356246e7 e2c5c809
-
- Submitted-by: "Jonathan I. Kamens" <jik@pit-manager.mit.edu>
- Posting-number: Volume 22, Issue 26
- Archive-name: undel2/part02
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 2 (of 3)."
- # Contents: col.c expunge.c lsdel.c undelete.c util.c
- # Wrapped by rsalz@papaya.bbn.com on Mon May 7 16:54:00 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'col.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'col.c'\"
- else
- echo shar: Extracting \"'col.c'\" \(5054 characters\)
- sed "s/^X//" >'col.c' <<'END_OF_FILE'
- X/*
- X * $Source: /afs/athena.mit.edu/user/j/jik/src/delete/RCS/col.c,v $
- X * $Author: jik $
- X *
- X * This program is part of a package including delete, undelete,
- X * lsdel, expunge and purge. The software suite is meant as a
- X * replacement for rm which allows for file recovery.
- X *
- X * Copyright (c) 1989 by the Massachusetts Institute of Technology.
- X * For copying and distribution information, see the file "mit-copyright.h."
- X */
- X
- X#if (!defined(lint) && !defined(SABER))
- X static char rcsid_col_c[] = "$Header: /afs/athena.mit.edu/user/j/jik/src/delete/RCS/col.c,v 1.6 89/11/22 21:24:21 jik Exp $";
- X#endif
- X
- X/*
- X * Note that this function has a lot of options I'm not really using
- X * because I took it out of other code that needed a lot more
- X * versatility.
- X */
- X
- X#include <stdio.h>
- X#include <strings.h>
- X#include "errors.h"
- X#include "delete_errs.h"
- X#include "col.h"
- X#include "mit-copyright.h"
- X
- X
- Xstatic int calc_string_width(), calc_widths(), num_width();
- Xstatic void trim_strings();
- X
- Xint column_array(strings, num_to_print, screen_width, column_width,
- X number_of_columns, margin, spread_flag,
- X number_flag, var_col_flag, outfile)
- Xchar **strings;
- XFILE *outfile;
- X{
- X char buf[BUFSIZ];
- X int updown, leftright, height;
- X int string_width;
- X int numwidth;
- X
- X numwidth = num_width(num_to_print);
- X if (! var_col_flag) {
- X string_width = calc_string_width(column_width, margin, number_flag,
- X num_to_print);
- X if (string_width <= 0) {
- X set_error(COL_COLUMNS_TOO_THIN);
- X error("calc_string_width");
- X return error_code;
- X }
- X trim_strings(strings, num_to_print, string_width);
- X } else if (calc_widths(strings, &screen_width, &column_width,
- X &number_of_columns, num_to_print, &margin,
- X spread_flag, number_flag)) {
- X error("calc_widths");
- X return error_code;
- X }
- X height = num_to_print / number_of_columns;
- X if (num_to_print % number_of_columns)
- X height++;
- X
- X if (number_flag) for (updown = 0; updown < height; updown++) {
- X for (leftright = updown; leftright < num_to_print; ) {
- X (void) sprintf(buf, "%*d. %s", numwidth, leftright+1,
- X strings[leftright]);
- X if ((leftright += height) >= num_to_print)
- X fprintf(outfile, "%s", buf );
- X else
- X fprintf(outfile, "%*s", -column_width, buf);
- X }
- X fprintf(outfile, "\n");
- X } else for (updown = 0; updown < height; updown++) {
- X for (leftright = updown; leftright < num_to_print; ) {
- X (void) sprintf(buf, "%s", strings[leftright]);
- X if ((leftright += height) >= num_to_print)
- X fprintf(outfile, "%s", buf );
- X else
- X fprintf(outfile, "%*s", -column_width, buf);
- X }
- X fprintf(outfile, "\n");
- X }
- X return 0;
- X}
- X
- Xstatic int calc_string_width(column_width, margin, number_flag, max_number)
- X{
- X int string_width;
- X
- X string_width = column_width - margin;
- X if (number_flag)
- X string_width = string_width - num_width(max_number) - strlen(". ");
- X return string_width;
- X}
- X
- X
- Xstatic void trim_strings(strings, number, width)
- Xchar **strings;
- X{
- X int loop;
- X
- X for (loop = 0; loop < number; loop++)
- X if (strlen(strings[loop]) > width)
- X strings[loop][width] = '\0';
- X}
- X
- X
- Xstatic int calc_widths(strings, screen_width, column_width, number_of_columns,
- X num_to_print, margin, spread_flag, number_flag)
- Xint *screen_width, *column_width, *number_of_columns, *margin;
- Xchar **strings;
- X{
- X int loop;
- X int maxlen, templen;
- X int spread;
- X
- X maxlen = templen = 0;
- X for (loop = 0; loop < num_to_print; loop++)
- X if (maxlen < (templen = strlen(strings[loop])))
- X maxlen = templen;
- X
- X *column_width = maxlen;
- X
- X if (number_flag)
- X *column_width = *column_width + num_width(num_to_print) +
- X strlen(". ");
- X
- X if (! spread_flag) {
- X *column_width += *margin;
- X if (! *number_of_columns) {
- X *number_of_columns = *screen_width / *column_width;
- X if (! *number_of_columns) {
- X (*number_of_columns)++;
- X *column_width -= *margin;
- X *margin = 0;
- X *screen_width = *column_width;
- X }
- X }
- X else
- X *screen_width = *number_of_columns * *column_width;
- X } else {
- X if (! *number_of_columns) {
- X *number_of_columns = *screen_width / (*column_width + *margin);
- X if (! *number_of_columns) {
- X (*number_of_columns)++;
- X *screen_width = *column_width;
- X *margin = 0;
- X }
- X spread = (*screen_width - *number_of_columns * *column_width)
- X / *number_of_columns;
- X *column_width += spread;
- X }
- X else {
- X if (*number_of_columns * (*column_width + *margin) >
- X *screen_width) {
- X *column_width += *margin;
- X *screen_width = *column_width;
- X } else {
- X spread = (*screen_width - (*number_of_columns *
- X *column_width)) /
- X *number_of_columns;
- X *column_width += spread;
- X }
- X }
- X }
- X return 0;
- X}
- X
- X
- X
- X
- Xstatic int num_width(number)
- Xint number;
- X{
- X char buf[BUFSIZ];
- X
- X (void) sprintf(buf, "%d", number);
- X return strlen(buf);
- X}
- END_OF_FILE
- if test 5054 -ne `wc -c <'col.c'`; then
- echo shar: \"'col.c'\" unpacked with wrong size!
- fi
- # end of 'col.c'
- fi
- if test -f 'expunge.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'expunge.c'\"
- else
- echo shar: Extracting \"'expunge.c'\" \(11211 characters\)
- sed "s/^X//" >'expunge.c' <<'END_OF_FILE'
- X/*
- X * $Source: /afs/athena.mit.edu/user/j/jik/src/delete/RCS/expunge.c,v $
- X * $Author: jik $
- X *
- X * This program is part of a package including delete, undelete,
- X * lsdel, expunge and purge. The software suite is meant as a
- X * replacement for rm which allows for file recovery.
- X *
- X * Copyright (c) 1989 by the Massachusetts Institute of Technology.
- X * For copying and distribution information, see the file "mit-copyright.h."
- X */
- X
- X#if (!defined(lint) && !defined(SABER))
- X static char rcsid_expunge_c[] = "$Header: /afs/athena.mit.edu/user/j/jik/src/delete/RCS/expunge.c,v 1.13 89/12/28 14:45:15 jik Exp $";
- X#endif
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/time.h>
- X#include <sys/dir.h>
- X#include <sys/param.h>
- X#include <strings.h>
- X#include <sys/stat.h>
- X#include <com_err.h>
- X#include <errno.h>
- X#include "col.h"
- X#include "directories.h"
- X#include "util.h"
- X#include "pattern.h"
- X#include "expunge.h"
- X#include "shell_regexp.h"
- X#include "mit-copyright.h"
- X#include "delete_errs.h"
- X#include "errors.h"
- X
- Xextern char *realloc();
- Xextern time_t current_time;
- Xextern int errno;
- X
- Xchar *whoami;
- X
- Xtime_t timev; /* minimum mod time before undeletion */
- X
- Xint interactive, /* query before each expunge */
- X recursive, /* expunge undeleted directories recursively */
- X noop, /* print what would be done instead of doing it */
- X verbose, /* print a line as each file is deleted */
- X force, /* do not ask for any confirmation */
- X listfiles, /* list files at toplevel */
- X yield, /* print yield of expunge at end */
- X f_links, /* follow symbolic links */
- X f_mounts; /* follow mount points */
- X
- Xint blocks_removed = 0;
- X
- X
- X
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X extern char *optarg;
- X extern int optind;
- X int arg;
- X
- X initialize_del_error_table();
- X
- X whoami = lastpart(argv[0]);
- X if (*whoami == 'p') { /* we're doing a purge */
- X if (argc > 1) {
- X set_error(PURGE_TOO_MANY_ARGS);
- X error("");
- X exit(1);
- X }
- X if (purge())
- X error("purge");
- X exit(error_occurred ? 1 : 0);
- X }
- X timev = 0;
- X yield = interactive = recursive = noop = verbose = listfiles = force = 0;
- X while ((arg = getopt(argc, argv, "t:irfnvlysm")) != EOF) {
- X switch (arg) {
- X case 't':
- X timev = atoi(optarg);
- X break;
- X case 'i':
- X interactive++;
- X break;
- X case 'r':
- X recursive++;
- X break;
- X case 'f':
- X force++;
- X break;
- X case 'n':
- X noop++;
- X break;
- X case 'v':
- X verbose++;
- X break;
- X case 'l':
- X listfiles++;
- X break;
- X case 'y':
- X yield++;
- X break;
- X case 's':
- X f_links++;
- X break;
- X case 'm':
- X f_mounts++;
- X break;
- X default:
- X usage();
- X exit(1);
- X }
- X }
- X report_errors = ! force;
- X
- X if (optind == argc) {
- X char *dir;
- X dir = "."; /* current working directory */
- X if (expunge(&dir, 1))
- X error("expunging .");
- X }
- X else if (expunge(&argv[optind], argc - optind))
- X error("expunge");
- X
- X exit((error_occurred && (! force)) ? 1 : 0);
- X}
- X
- X
- X
- X
- X
- Xpurge()
- X{
- X char *home;
- X int retval;
- X
- X home = Malloc((unsigned) MAXPATHLEN);
- X if (! home) {
- X set_error(errno);
- X error("purge");
- X return error_code;
- X }
- X timev = interactive = noop = verbose = force = 0;
- X yield = listfiles = recursive = 1;
- X if (retval = get_home(home)) {
- X error("purge");
- X return retval;
- X }
- X
- X printf("Please be patient.... this may take a while.\n\n");
- X
- X if (retval = expunge(&home, 1)) {
- X error("expunge");
- X return retval;
- X }
- X return 0;
- X}
- X
- X
- X
- X
- Xusage()
- X{
- X fprintf(stderr, "Usage: %s [ options ] [ filename [ ... ]]\n", whoami);
- X fprintf(stderr, "Options are:\n");
- X fprintf(stderr, " -r recursive\n");
- X fprintf(stderr, " -i interactive\n");
- X fprintf(stderr, " -f force\n");
- X fprintf(stderr, " -t n n-day-or-older expunge\n");
- X fprintf(stderr, " -n noop\n");
- X fprintf(stderr, " -v verbose\n");
- X fprintf(stderr, " -l list files before expunging\n");
- X fprintf(stderr, " -s follow symbolic links to directories\n");
- X fprintf(stderr, " -m follow mount points\n");
- X fprintf(stderr, " -y print yield of expunge\n");
- X fprintf(stderr, " -- end options and start filenames\n");
- X}
- X
- X
- X
- X
- X
- Xint expunge(files, num)
- Xchar **files;
- Xint num;
- X{
- X char **found_files;
- X int num_found;
- X int status = 0;
- X int total = 0;
- X filerec *current;
- X int retval;
- X
- X if (initialize_tree())
- X exit(1);
- X
- X for ( ; num ; num--) {
- X retval = get_the_files(files[num - 1], &num_found, &found_files);
- X if (retval) {
- X error(files[num - 1]);
- X return retval;
- X }
- X
- X if (num_found) {
- X num_found = process_files(found_files, num_found);
- X if (num_found < 0) {
- X error("process_files");
- X return error_code;
- X }
- X }
- X
- X total += num_found;
- X if (! num_found) if (! force) {
- X /*
- X * There are three different situations here. Eiter we
- X * are dealing with an existing directory with no
- X * deleted files in it, or we are deleting with a
- X * non-existing deleted file with wildcards, or we are
- X * dealing with a non-existing deleted file without
- X * wildcards. In the former case we print nothing, and
- X * in the latter cases we print either "no match" or
- X * "not found" respectively
- X */
- X if (no_wildcards(files[num - 1])) {
- X if (! directory_exists(files[num - 1])) {
- X set_error(ENOENT);
- X error(files[num - 1]);
- X }
- X }
- X else {
- X set_error(ENOMATCH);
- X error(files[num - 1]);
- X }
- X }
- X }
- X if (total && listfiles) {
- X if (retval = list_files()) {
- X error("list_files");
- X return retval;
- X }
- X if (! force) if (! top_level()) {
- X set_status(EXPUNGE_NOT_EXPUNGED);
- X return error_code;
- X }
- X }
- X current = get_root_tree();
- X if (current) {
- X if (retval = expunge_specified(current)) {
- X error("expunge_specified");
- X status = retval;
- X }
- X }
- X current = get_cwd_tree();
- X if (current) {
- X if (retval = expunge_specified(current)) {
- X error("expunge_specified");
- X status = retval;
- X }
- X }
- X if (yield) {
- X if (noop)
- X printf("Total that would be expunged: %dk\n",
- X blk_to_k(blocks_removed));
- X else
- X printf("Total expunged: %dk\n", blk_to_k(blocks_removed));
- X }
- X return status;
- X}
- X
- X
- X
- Xexpunge_specified(leaf)
- Xfilerec *leaf;
- X{
- X int status = 0;
- X int do_it = 1;
- X int retval;
- X
- X if ((leaf->specified) && ((leaf->specs.st_mode & S_IFMT) == S_IFDIR)) {
- X char buf[MAXPATHLEN];
- X
- X if (retval = get_leaf_path(leaf, buf)) {
- X error("get_leaf_path");
- X return retval;
- X }
- X (void) convert_to_user_name(buf, buf);
- X
- X if (interactive) {
- X printf("%s: Expunge directory %s? ", whoami, buf);
- X status = (! (do_it = yes()));
- X }
- X }
- X if (do_it) {
- X if (leaf->dirs) {
- X if (retval = expunge_specified(leaf->dirs)) {
- X error("expunge_specified");
- X status = retval;
- X }
- X }
- X if (leaf->files) {
- X if (retval = expunge_specified(leaf->files)) {
- X error("expunge_specified");
- X status = retval;
- X }
- X }
- X }
- X if (leaf->specified && (! status)) {
- X if (retval = really_do_expunge(leaf)) {
- X error("really_do_expunge");
- X status = retval;
- X }
- X }
- X if (leaf->next) {
- X if (retval = expunge_specified(leaf->next)) {
- X error("expunge_specified");
- X status = retval;
- X }
- X }
- X
- X free_leaf(leaf);
- X return status;
- X}
- X
- X
- Xprocess_files(files, num)
- Xchar **files;
- Xint num;
- X{
- X int i, skipped = 0;
- X filerec *leaf;
- X
- X for (i = 0; i < num; i++) {
- X if (add_path_to_tree(files[i], &leaf)) {
- X error("add_path_to_tree");
- X return -1;
- X }
- X free(files[i]);
- X if (! timed_out(leaf, current_time, timev)) {
- X free_leaf(leaf);
- X skipped++;
- X }
- X }
- X free((char *) files);
- X return(num-skipped);
- X}
- X
- X
- X
- X
- X
- X
- X
- X
- X
- Xreally_do_expunge(file_ent)
- Xfilerec *file_ent;
- X{
- X char real[MAXPATHLEN], user[MAXPATHLEN];
- X int status;
- X int retval;
- X
- X if (retval = get_leaf_path(file_ent, real)) {
- X error("get_leaf_path");
- X return retval;
- X }
- X (void) convert_to_user_name(real, user);
- X
- X if (interactive) {
- X printf ("%s: Expunge %s (%dk)? ", whoami, user,
- X blk_to_k(file_ent->specs.st_blocks));
- X if (! yes()) {
- X set_status(EXPUNGE_NOT_EXPUNGED);
- X return error_code;
- X }
- X }
- X
- X if (noop) {
- X blocks_removed += file_ent->specs.st_blocks;
- X printf("%s: %s (%dk) would be expunged (%dk total)\n", whoami, user,
- X blk_to_k(file_ent->specs.st_blocks),
- X blk_to_k(blocks_removed));
- X return 0;
- X }
- X
- X if ((file_ent->specs.st_mode & S_IFMT) == S_IFDIR)
- X status = rmdir(real);
- X else
- X status = unlink(real);
- X if (! status) {
- X blocks_removed += file_ent->specs.st_blocks;
- X if (verbose)
- X printf("%s: %s (%dk) expunged (%dk total)\n", whoami, user,
- X blk_to_k(file_ent->specs.st_blocks),
- X blk_to_k(blocks_removed));
- X return 0;
- X }
- X else {
- X set_error(errno);
- X error(real);
- X return error_code;
- X }
- X}
- X
- X
- X
- X
- X
- X
- X
- X
- X
- Xtop_level()
- X{
- X if (interactive) {
- Xprintf("The above files, which have been marked for deletion, are about to be\n");
- Xprintf("expunged forever! You will be asked for confirmation before each file is\n");
- Xprintf("deleted. Do you wish to continue [return = no]? ");
- X }
- X else {
- Xprintf("The above files, which have been marked for deletion, are about to be\n");
- Xprintf("expunged forever! Make sure you don't need any of them before continuing.\n");
- Xprintf("Do you wish to continue [return = no]? ");
- X }
- X return (yes());
- X}
- X
- X
- X
- X
- X
- Xlist_files()
- X{
- X filerec *current;
- X char **strings;
- X int num;
- X int retval;
- X
- X strings = (char **) Malloc(sizeof(char *));
- X num = 0;
- X if (! strings) {
- X set_error(errno);
- X error("Malloc");
- X return error_code;
- X }
- X
- X printf("The following deleted files are going to be expunged: \n\n");
- X
- X current = get_root_tree();
- X if (retval = accumulate_names(current, &strings, &num)) {
- X error("accumulate_names");
- X return retval;
- X }
- X current = get_cwd_tree();
- X if (retval = accumulate_names(current, &strings, &num)) {
- X error("accumulate_names");
- X return retval;
- X }
- X if (retval = column_array(strings, num, DEF_SCR_WIDTH, 0, 0, 2, 1, 0,
- X 1, stdout)) {
- X error("column_array");
- X return retval;
- X }
- X
- X printf("\n");
- X return(0);
- X}
- X
- X
- X
- X
- X
- Xint get_the_files(name, num_found, found)
- Xchar *name;
- Xint *num_found;
- Xchar ***found;
- X{
- X int retval;
- X int options;
- X
- X options = FIND_DELETED | FIND_CONTENTS | RECURS_DELETED;
- X if (recursive)
- X options |= RECURS_FIND_DELETED;
- X if (f_mounts)
- X options |= FOLLW_MOUNTPOINTS;
- X if (f_links)
- X options |= FOLLW_LINKS;
- X
- X retval = find_matches(name, num_found, found, options);
- X if (retval) {
- X error("find_matches");
- X return retval;
- X }
- X
- X return 0;
- X}
- END_OF_FILE
- if test 11211 -ne `wc -c <'expunge.c'`; then
- echo shar: \"'expunge.c'\" unpacked with wrong size!
- fi
- # end of 'expunge.c'
- fi
- if test -f 'lsdel.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'lsdel.c'\"
- else
- echo shar: Extracting \"'lsdel.c'\" \(7280 characters\)
- sed "s/^X//" >'lsdel.c' <<'END_OF_FILE'
- X/*
- X * $Source: /afs/athena.mit.edu/user/j/jik/src/delete/RCS/lsdel.c,v $
- X * $Author: jik $
- X *
- X * This program is a replacement for rm. Instead of actually deleting
- X * files, it marks them for deletion by prefixing them with a ".#"
- X * prefix.
- X *
- X * Copyright (c) 1989 by the Massachusetts Institute of Technology.
- X * For copying and distribution information, see the file "mit-copyright.h."
- X */
- X
- X#if (!defined(lint) && !defined(SABER))
- X static char rcsid_lsdel_c[] = "$Header: /afs/athena.mit.edu/user/j/jik/src/delete/RCS/lsdel.c,v 1.9 89/11/22 21:31:08 jik Exp $";
- X#endif
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/dir.h>
- X#include <sys/param.h>
- X#include <sys/stat.h>
- X#include <strings.h>
- X#include <errno.h>
- X#include <com_err.h>
- X#include "col.h"
- X#include "util.h"
- X#include "directories.h"
- X#include "pattern.h"
- X#include "lsdel.h"
- X#include "shell_regexp.h"
- X#include "mit-copyright.h"
- X#include "delete_errs.h"
- X#include "errors.h"
- X
- Xchar *realloc();
- Xextern time_t current_time;
- Xextern int errno;
- X
- Xint block_total = 0;
- Xint dirsonly, recursive, yield, f_links, f_mounts;
- Xtime_t timev;
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X extern char *optarg;
- X extern int optind;
- X int arg;
- X
- X whoami = lastpart(argv[0]);
- X
- X dirsonly = recursive = timev = yield = f_links = f_mounts = 0;
- X while ((arg = getopt(argc, argv, "drt:ysm")) != -1) {
- X switch (arg) {
- X case 'd':
- X dirsonly++;
- X break;
- X case 'r':
- X recursive++;
- X break;
- X case 't':
- X timev = atoi(optarg);
- X break;
- X case 'y':
- X yield++;
- X break;
- X case 's':
- X f_links++;
- X break;
- X case 'm':
- X f_mounts++;
- X break;
- X default:
- X usage();
- X exit(1);
- X }
- X }
- X if (optind == argc) {
- X char *cwd;
- X
- X cwd = ".";
- X
- X if (ls(&cwd, 1))
- X error("ls of .");
- X }
- X else if (ls(&argv[optind], argc - optind))
- X error ("ls");
- X
- X exit (error_occurred ? 1 : 0);
- X}
- X
- X
- X
- X
- X
- X
- Xusage()
- X{
- X fprintf(stderr, "Usage: %s [ options ] [ filename [ ...]]\n", whoami);
- X fprintf(stderr, "Options are:\n");
- X fprintf(stderr, " -d list directory names, not contents\n");
- X fprintf(stderr, " -r recursive\n");
- X fprintf(stderr, " -t n list n-day-or-older files only\n");
- X fprintf(stderr, " -y report total space taken up by files\n");
- X fprintf(stderr, " -s follow symbolic links to directories\n");
- X fprintf(stderr, " -m follow mount points\n");
- X}
- X
- X
- X
- X
- Xls(args, num)
- Xchar **args;
- Xint num;
- X{
- X char **found_files;
- X int num_found = 0, total = 0;
- X int status = 0;
- X int retval;
- X
- X initialize_del_error_table();
- X
- X if (retval = initialize_tree()) {
- X error("initialize_tree");
- X return retval;
- X }
- X
- X for ( ; num; num--) {
- X if (retval = get_the_files(args[num - 1], &num_found,
- X &found_files)) {
- X error(args[num - 1]);
- X status = retval;
- X continue;
- X }
- X
- X if (num_found) {
- X num_found = process_files(found_files, num_found);
- X if (num_found < 0) {
- X error("process_files");
- X status = error_code;
- X continue;
- X }
- X total += num_found;
- X }
- X else {
- X /* What we do at this point depends on exactly what the
- X * filename is. There are several possible conditions:
- X * 1. The filename has no wildcards in it, which means that
- X * if we couldn't find it, that means it doesn't
- X * exist. Print a not found error.
- X * 2. Filename is an existing directory, with no deleted
- X * files in it. Print nothing.
- X * 3. Filename doesn't exist, and there are wildcards in
- X * it. Print "no match".
- X * None of these are considered error conditions, so we
- X * don't set the error flag.
- X */
- X if (no_wildcards(args[num - 1])) {
- X if (! directory_exists(args[num - 1])) {
- X set_error(ENOENT);
- X error(args[num - 1]);
- X status = error_code;
- X continue;
- X }
- X }
- X else {
- X set_error(ENOMATCH);
- X error(args[num - 1]);
- X status = error_code;
- X continue;
- X }
- X }
- X }
- X if (total) {
- X if (list_files()) {
- X error("list_files");
- X return error_code;
- X }
- X }
- X if (yield)
- X printf("\nTotal space taken up by file%s: %dk\n",
- X (total == 1 ? "" : "s"), blk_to_k(block_total));
- X
- X return status;
- X}
- X
- X
- X
- X
- Xint get_the_files(name, number_found, found)
- Xchar *name;
- Xint *number_found;
- Xchar ***found;
- X{
- X int retval;
- X int options;
- X
- X options = FIND_DELETED | FIND_CONTENTS;
- X if (recursive)
- X options |= RECURS_FIND_DELETED;
- X if (! dirsonly)
- X options |= RECURS_DELETED;
- X if (f_mounts)
- X options |= FOLLW_MOUNTPOINTS;
- X if (f_links)
- X options |= FOLLW_LINKS;
- X
- X retval = find_matches(name, number_found, found, options);
- X if (retval) {
- X error("find_matches");
- X return retval;
- X }
- X
- X return 0;
- X}
- X
- X
- X
- X
- X
- X
- Xprocess_files(files, num)
- Xchar **files;
- Xint num;
- X{
- X int i;
- X filerec *leaf;
- X
- X for (i = 0; i < num; i++) {
- X if (add_path_to_tree(files[i], &leaf)) {
- X error("add_path_to_tree");
- X return -1;
- X }
- X free(files[i]);
- X if (! timed_out(leaf, current_time, timev)) {
- X free_leaf(leaf);
- X num--;
- X continue;
- X }
- X block_total += leaf->specs.st_blocks;
- X }
- X free((char *) files);
- X return(num);
- X}
- X
- X
- X
- X
- X
- Xlist_files()
- X{
- X filerec *current;
- X char **strings;
- X int num;
- X int retval;
- X
- X strings = (char **) Malloc((unsigned) sizeof(char *));
- X num = 0;
- X if (! strings) {
- X set_error(errno);
- X error("Malloc");
- X return error_code;
- X }
- X current = get_root_tree();
- X if (retval = accumulate_names(current, &strings, &num)) {
- X error("accumulate_names");
- X return retval;
- X }
- X current = get_cwd_tree();
- X if (retval = accumulate_names(current, &strings, &num)) {
- X error("accumulate_names");
- X return retval;
- X }
- X
- X if (retval = sort_files(strings, num)) {
- X error("sort_files");
- X return retval;
- X }
- X
- X if (retval = unique(&strings, &num)) {
- X error("unique");
- X return retval;
- X }
- X
- X if (retval = column_array(strings, num, DEF_SCR_WIDTH, 0, 0, 2, 1, 0,
- X 1, stdout)) {
- X error("column_array");
- X return retval;
- X }
- X
- X for ( ; num; num--)
- X free(strings[num - 1]);
- X free((char *) strings);
- X return 0;
- X}
- X
- X
- Xint sort_files(data, num_data)
- Xchar **data;
- Xint num_data;
- X{
- X qsort((char *) data, num_data, sizeof(char *), strcmp);
- X
- X return 0;
- X}
- X
- X
- Xint unique(the_files, number)
- Xchar ***the_files;
- Xint *number;
- X{
- X int i, last;
- X int offset;
- X char **files;
- X
- X files = *the_files;
- X for (last = 0, i = 1; i < *number; i++) {
- X if (! strcmp(files[last], files[i])) {
- X free (files[i]);
- X free (files[i]);
- X files[i] = (char *) NULL;
- X }
- X else
- X last = i;
- X }
- X
- X for (offset = 0, i = 0; i + offset < *number; i++) {
- X if (! files[i])
- X offset++;
- X if (i + offset < *number)
- X files[i] = files[i + offset];
- X }
- X *number -= offset;
- X files = (char **) realloc((char *) files,
- X (unsigned) (sizeof(char *) * *number));
- X if (! files) {
- X set_error(errno);
- X error("realloc");
- X return errno;
- X }
- X
- X *the_files = files;
- X return 0;
- X}
- END_OF_FILE
- if test 7280 -ne `wc -c <'lsdel.c'`; then
- echo shar: \"'lsdel.c'\" unpacked with wrong size!
- fi
- # end of 'lsdel.c'
- fi
- if test -f 'undelete.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'undelete.c'\"
- else
- echo shar: Extracting \"'undelete.c'\" \(12500 characters\)
- sed "s/^X//" >'undelete.c' <<'END_OF_FILE'
- X/*
- X * $Source: /afs/athena.mit.edu/user/j/jik/src/delete/RCS/undelete.c,v $
- X * $Author: jik $
- X *
- X * This program is part of a package including delete, undelete,
- X * lsdel, expunge and purge. The software suite is meant as a
- X * replacement for rm which allows for file recovery.
- X *
- X * Copyright (c) 1989 by the Massachusetts Institute of Technology.
- X * For copying and distribution information, see the file "mit-copyright.h."
- X */
- X
- X#if (!defined(lint) && !defined(SABER))
- X static char rcsid_undelete_c[] = "$Header: /afs/athena.mit.edu/user/j/jik/src/delete/RCS/undelete.c,v 1.19 89/12/15 04:39:31 jik Exp $";
- X#endif
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/dir.h>
- X#include <sys/param.h>
- X#include <strings.h>
- X#include <sys/stat.h>
- X#include <com_err.h>
- X#include <errno.h>
- X#include "delete_errs.h"
- X#include "directories.h"
- X#include "pattern.h"
- X#include "util.h"
- X#include "undelete.h"
- X#include "shell_regexp.h"
- X#include "mit-copyright.h"
- X#include "errors.h"
- X
- Xextern char *realloc();
- Xextern int errno;
- X
- Xint interactive, recursive, verbose, directoriesonly, noop, force;
- X
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X extern char *optarg;
- X extern int optind;
- X int arg;
- X int retval;
- X
- X initialize_del_error_table();
- X
- X whoami = lastpart(argv[0]);
- X interactive = recursive = verbose = directoriesonly = noop = force = 0;
- X
- X while ((arg = getopt(argc, argv, "firvnR")) != -1) {
- X switch (arg) {
- X case 'f':
- X force++;
- X break;
- X case 'i':
- X interactive++;
- X break;
- X case 'r':
- X recursive++;
- X if (directoriesonly) {
- X fprintf(stderr, "%s: -r and -R and mutually exclusive.\n",
- X whoami);
- X usage();
- X exit(1);
- X }
- X break;
- X case 'v':
- X verbose++;
- X break;
- X case 'n':
- X noop++;
- X break;
- X case 'R':
- X directoriesonly++;
- X if (recursive) {
- X fprintf(stderr, "%s: -r and -R are mutually exclusive.\n",
- X whoami);
- X usage();
- X exit(1);
- X }
- X break;
- X default:
- X usage();
- X exit(1);
- X }
- X }
- X
- X report_errors = ! force;
- X
- X if (optind == argc) {
- X if (interactive_mode())
- X error("interactive_mode");
- X }
- X else while (optind < argc) {
- X retval = undelete(argv[optind]);
- X if (retval)
- X error(argv[optind]);
- X optind++;
- X }
- X exit(((! force) && error_occurred) ? 1 : 0);
- X}
- X
- X
- X
- Xinteractive_mode()
- X{
- X char buf[MAXPATHLEN];
- X char *ptr;
- X int status = 0;
- X int retval;
- X
- X if (verbose) {
- X printf("Enter the files to be undeleted, one file per line.\n");
- X printf("Hit <RETURN> on a line by itself to exit.\n\n");
- X }
- X do {
- X printf("%s: ", whoami);
- X ptr = fgets(buf, MAXPATHLEN, stdin);
- X if (! ptr) {
- X printf("\n");
- X return status;
- X }
- X ptr = index(buf, '\n'); /* fgets breakage */
- X if (ptr)
- X *ptr = '\0';
- X if (! *buf)
- X return status;
- X retval = undelete(buf);
- X if (retval) {
- X error(buf);
- X status = retval;
- X }
- X } while (*buf);
- X return status;
- X}
- X
- X
- X
- Xusage()
- X{
- X fprintf(stderr, "Usage: %s [ options ] [filename ...]\n", whoami);
- X fprintf(stderr, "Options are:\n");
- X fprintf(stderr, " -r recursive\n");
- X fprintf(stderr, " -i interactive\n");
- X fprintf(stderr, " -f force\n");
- X fprintf(stderr, " -v verbose\n");
- X fprintf(stderr, " -n noop\n");
- X fprintf(stderr, " -R directories only (i.e. no recursion)\n");
- X fprintf(stderr, " -- end options and start filenames\n");
- X fprintf(stderr, "-r and -D are mutually exclusive\n");
- X}
- X
- Xundelete(name)
- Xchar *name;
- X{
- X char **found_files;
- X int num_found;
- X int status = 0;
- X filerec *current;
- X int retval;
- X
- X if (retval = get_the_files(name, &num_found, &found_files)) {
- X error(name);
- X return retval;
- X }
- X
- X if (num_found) {
- X if (retval = process_files(found_files, num_found)) {
- X error(name);
- X return retval;
- X }
- X if (*name == '/')
- X current = get_root_tree();
- X else
- X current = get_cwd_tree();
- X
- X status = recurs_and_undelete(current);
- X if (status) {
- X error(name);
- X return status;
- X }
- X }
- X else {
- X if (no_wildcards(name)) {
- X set_error(ENOENT)
- X }
- X else
- X set_error(ENOMATCH);
- X error(name);
- X return error_code;
- X }
- X
- X return status;
- X}
- X
- X
- X
- X
- X
- Xint recurs_and_undelete(leaf)
- Xfilerec *leaf;
- X{
- X int status = 0;
- X int retval;
- X
- X if (leaf->specified) {
- X retval = do_undelete(leaf);
- X if (retval) {
- X error("do_undelete");
- X return retval;
- X }
- X }
- X
- X if (leaf->dirs) {
- X retval = recurs_and_undelete(leaf->dirs);
- X if (retval) {
- X error("recurs_and_undelete");
- X status = retval;
- X }
- X }
- X
- X if (leaf->files) {
- X retval = recurs_and_undelete(leaf->files);
- X if (retval) {
- X error("recurs_and_undelete");
- X status = retval;
- X }
- X }
- X
- X if (leaf->next) {
- X retval = recurs_and_undelete(leaf->next);
- X if (retval) {
- X error("recurs_and_undelete");
- X status = retval;
- X }
- X }
- X
- X free_leaf(leaf);
- X
- X return status;
- X}
- X
- X
- X
- X
- X
- X
- Xint process_files(files, num)
- Xchar **files;
- Xint num;
- X{
- X int i;
- X listrec *filelist;
- X struct filrec *not_needed;
- X int retval;
- X
- X filelist = (listrec *) Malloc((unsigned) (sizeof(listrec) * num));
- X if (! filelist) {
- X set_error(errno);
- X error("process_files");
- X return error_code;
- X }
- X
- X for (i = 0; i < num; i++) {
- X filelist[i].real_name = Malloc((unsigned) (strlen(files[i]) + 1));
- X if (! filelist[i].real_name) {
- X set_error(errno);
- X error("process_files");
- X return error_code;
- X }
- X (void) strcpy(filelist[i].real_name, files[i]);
- X filelist[i].user_name = Malloc((unsigned) (strlen(files[i]) + 1));
- X if (! filelist[i].user_name) {
- X set_error(errno);
- X error("process_files");
- X return error_code;
- X }
- X (void) convert_to_user_name(files[i], filelist[i].user_name);
- X free(files[i]);
- X }
- X free((char *) files);
- X
- X if (retval = sort_files(filelist, num)) {
- X error("sort_files");
- X return retval;
- X }
- X if (retval = unique(&filelist, &num)) {
- X error("unique");
- X return retval;
- X }
- X if (retval = initialize_tree()) {
- X error("initialize_tree");
- X return retval;
- X }
- X
- X for (i = 0; i < num; i++) {
- X if (retval = add_path_to_tree(filelist[i].real_name, ¬_needed)) {
- X error("add_path_to_tree");
- X return retval;
- X }
- X else {
- X free(filelist[i].real_name);
- X free(filelist[i].user_name);
- X }
- X }
- X free((char *) filelist);
- X return 0;
- X}
- X
- X
- X
- X
- X
- X
- X
- X
- Xdo_undelete(file_ent)
- Xfilerec *file_ent;
- X{
- X struct stat stat_buf;
- X char user_name[MAXPATHLEN], real_name[MAXPATHLEN];
- X int retval;
- X
- X if (retval = get_leaf_path(file_ent, real_name)) {
- X if (! force)
- X fprintf(stderr, "%s: %s: %s\n", whoami, "get_leaf_path",
- X error_message(retval));
- X return retval;
- X }
- X
- X (void) convert_to_user_name(real_name, user_name);
- X
- X if (interactive) {
- X if ((file_ent->specs.st_mode & S_IFMT) == S_IFDIR)
- X printf("%s: Undelete directory %s? ", whoami, user_name);
- X else
- X printf("%s: Undelete %s? ", whoami, user_name);
- X if (! yes()) {
- X set_status(UNDEL_NOT_UNDELETED);
- X return error_code;
- X }
- X }
- X if (! lstat(user_name, &stat_buf)) if (! force) {
- X printf("%s: An undeleted %s already exists.\n", whoami, user_name);
- X printf("Do you wish to continue with the undelete and overwrite that version? ");
- X if (! yes()) {
- X set_status(UNDEL_NOT_UNDELETED);
- X return error_code;
- X }
- X if (! noop) if (retval = unlink_completely(user_name)) {
- X error(user_name);
- X return retval;
- X }
- X }
- X if (noop) {
- X printf("%s: %s would be undeleted\n", whoami, user_name);
- X return 0;
- X }
- X
- X if (retval = do_file_rename(real_name, user_name)) {
- X error("do_file_rename");
- X return retval;
- X }
- X else {
- X if (verbose)
- X printf("%s: %s undeleted\n", whoami, user_name);
- X return 0;
- X }
- X}
- X
- X
- X
- X
- Xdo_file_rename(real_name, user_name)
- Xchar *real_name, *user_name;
- X{
- X char *ptr;
- X int retval;
- X char error_buf[MAXPATHLEN+MAXPATHLEN+14];
- X char old_name[MAXPATHLEN], new_name[MAXPATHLEN];
- X char buf[MAXPATHLEN];
- X
- X (void) strcpy(old_name, real_name);
- X (void) strcpy(new_name, real_name);
- X
- X while (ptr = strrindex(new_name, ".#")) {
- X (void) convert_to_user_name(ptr, ptr);
- X (void) strcpy(ptr, firstpart(ptr, buf));
- X (void) strcpy(&old_name[ptr - new_name],
- X firstpart(&old_name[ptr - new_name], buf));
- X if (rename(old_name, new_name)) {
- X set_error(errno);
- X (void) sprintf(error_buf, "renaming %s to %s",
- X old_name, new_name);
- X error(error_buf);
- X return error_code;
- X }
- X if (ptr > new_name) {
- X *--ptr = '\0';
- X old_name[ptr - new_name] = '\0';
- X }
- X }
- X if (retval = change_path(real_name, user_name)) {
- X error("change_path");
- X return retval;
- X }
- X
- X return 0;
- X}
- X
- X
- X
- X
- X
- X
- Xfilecmp(file1, file2)
- Xlistrec *file1, *file2;
- X{
- X return(strcmp(file1->user_name, file2->user_name));
- X}
- X
- X
- X
- Xint sort_files(data, num_data)
- Xlistrec *data;
- Xint num_data;
- X{
- X qsort((char *) data, num_data, sizeof(listrec), filecmp);
- X
- X return 0;
- X}
- X
- X
- X
- X
- X
- Xint unique(the_files, number)
- Xlistrec **the_files;
- Xint *number;
- X{
- X int i, last;
- X int offset;
- X listrec *files;
- X
- X files = *the_files;
- X for (last = 0, i = 1; i < *number; i++) {
- X if (! strcmp(files[last].user_name, files[i].user_name)) {
- X int better;
- X
- X better = choose_better(files[last].real_name,
- X files[i].real_name);
- X if (better == 1) { /* the first one is better */
- X free (files[i].real_name);
- X free (files[i].user_name);
- X files[i].real_name = (char *) NULL;
- X }
- X else {
- X free (files[last].real_name);
- X free (files[last].user_name);
- X files[last].real_name = (char *) NULL;
- X last = i;
- X }
- X }
- X else
- X last = i;
- X }
- X
- X for (offset = 0, i = 0; i + offset < *number; i++) {
- X if (! files[i].real_name)
- X offset++;
- X if (i + offset < *number)
- X files[i] = files[i + offset];
- X }
- X *number -= offset;
- X files = (listrec *) realloc((char *) files,
- X (unsigned) (sizeof(listrec) * *number));
- X if (! files) {
- X set_error(errno);
- X error("realloc");
- X return errno;
- X }
- X
- X *the_files = files;
- X return 0;
- X}
- X
- X
- X
- X
- Xchoose_better(str1, str2)
- Xchar *str1, *str2;
- X{
- X char *pos1, *pos2;
- X
- X pos1 = strindex(str1, ".#");
- X pos2 = strindex(str2, ".#");
- X while (pos1 && pos2) {
- X if (pos1 - str1 < pos2 - str2)
- X return(2);
- X else if (pos2 - str2 < pos1 - str1)
- X return(1);
- X pos1 = strindex(pos1 + 1, ".#");
- X pos2 = strindex(pos2 + 1, ".#");
- X }
- X if (! pos1)
- X return(1);
- X else
- X return(2);
- X}
- X
- X
- X
- X
- X
- Xunlink_completely(filename)
- Xchar *filename;
- X{
- X char buf[MAXPATHLEN];
- X struct stat stat_buf;
- X DIR *dirp;
- X struct direct *dp;
- X int retval;
- X int status = 0;
- X
- X if (lstat(filename, &stat_buf)) {
- X set_error(errno);
- X error(filename);
- X return error_code;
- X }
- X
- X if ((stat_buf.st_mode & S_IFMT) == S_IFDIR) {
- X dirp = Opendir(filename);
- X if (! dirp) {
- X set_error(errno);
- X error(filename);
- X return error_code;
- X }
- X
- X for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
- X if (is_dotfile(dp->d_name))
- X continue;
- X (void) strcpy(buf, append(filename, dp->d_name));
- X if (retval = unlink_completely(buf)) {
- X error(buf);
- X status = retval;
- X }
- X }
- X closedir(dirp);
- X if (retval = rmdir(filename)) {
- X set_error(errno);
- X error(filename);
- X return error_code;
- X }
- X }
- X else if (retval = unlink(filename)) {
- X set_error(errno);
- X error(filename);
- X return error_code;
- X }
- X
- X return status;
- X}
- X
- X
- X
- X
- Xint get_the_files(name, num_found, found)
- Xchar *name;
- Xint *num_found;
- Xchar ***found;
- X{
- X int retval;
- X int options;
- X
- X options = FIND_DELETED;
- X if (recursive)
- X options |= RECURS_DELETED;
- X if (! directoriesonly)
- X options |= FIND_CONTENTS;
- X
- X retval = find_matches(name, num_found, found, options);
- X if (retval) {
- X error("find_matches");
- X return retval;
- X }
- X
- X return 0;
- X}
- END_OF_FILE
- if test 12500 -ne `wc -c <'undelete.c'`; then
- echo shar: \"'undelete.c'\" unpacked with wrong size!
- fi
- # end of 'undelete.c'
- fi
- if test -f 'util.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'util.c'\"
- else
- echo shar: Extracting \"'util.c'\" \(7849 characters\)
- sed "s/^X//" >'util.c' <<'END_OF_FILE'
- X/*
- X * $Source: /afs/athena.mit.edu/user/j/jik/src/delete/RCS/util.c,v $
- X * $Author: jik $
- X *
- X * This program is a replacement for rm. Instead of actually deleting
- X * files, it marks them for deletion by prefixing them with a ".#"
- X * prefix.
- X *
- X * Copyright (c) 1989 by the Massachusetts Institute of Technology.
- X * For copying and distribution information, see the file "mit-copyright.h."
- X */
- X
- X#if (!defined(lint) && !defined(SABER))
- X static char rcsid_util_c[] = "$Header: /afs/athena.mit.edu/user/j/jik/src/delete/RCS/util.c,v 1.15 90/01/11 03:47:11 jik Exp $";
- X#endif
- X
- X#include <stdio.h>
- X#include <sys/param.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <sys/dir.h>
- X#include <strings.h>
- X#include <pwd.h>
- X#include <errno.h>
- X#ifdef AFS_MOUNTPOINTS
- X#include <sys/ioctl.h>
- X#include <afs/vice.h>
- X#include <afs/venus.h>
- X#endif
- X#include "delete_errs.h"
- X#include "directories.h"
- X#include "util.h"
- X#include "mit-copyright.h"
- X#include "errors.h"
- X
- Xextern char *getenv();
- Xextern uid_t getuid();
- Xextern int errno;
- X
- Xchar *convert_to_user_name(real_name, user_name)
- Xchar real_name[];
- Xchar user_name[]; /* RETURN */
- X{
- X char *ptr, *q;
- X
- X (void) strcpy(user_name, real_name);
- X while (ptr = strrindex(user_name, ".#")) {
- X for (q = ptr; *(q + 2); q++)
- X *q = *(q + 2);
- X *q = '\0';
- X }
- X return (user_name);
- X}
- X
- X
- X
- X
- X
- Xchar *strindex(str, sub_str)
- Xchar *str, *sub_str;
- X{
- X char *ptr = str;
- X while (ptr = index(ptr, *sub_str)) {
- X if (! strncmp(ptr, sub_str, strlen(sub_str)))
- X return(ptr);
- X ptr++;
- X }
- X return ((char *) NULL);
- X}
- X
- X
- X
- Xchar *strrindex(str, sub_str)
- Xchar *str, *sub_str;
- X{
- X char *ptr;
- X
- X if (strlen(str))
- X ptr = &str[strlen(str) - 1];
- X else
- X return((char *) NULL);
- X while ((*ptr != *sub_str) && (ptr != str)) ptr--;
- X while (ptr != str) {
- X if (! strncmp(ptr, sub_str, strlen(sub_str)))
- X return(ptr);
- X ptr--;
- X while ((*ptr != *sub_str) && (ptr != str)) ptr--;
- X }
- X if (! strncmp(ptr, sub_str, strlen(sub_str)))
- X return(str);
- X else
- X return ((char *) NULL);
- X}
- X
- X
- X/*
- X * NOTE: Append uses a static array, so its return value must be
- X * copied immediately.
- X */
- Xchar *append(filepath, filename)
- Xchar *filepath, *filename;
- X{
- X static char buf[MAXPATHLEN];
- X
- X (void) strcpy(buf, filepath);
- X if ((! *filename) || (! *filepath)) {
- X (void) strcpy(buf, filename);
- X return(buf);
- X }
- X if (buf[strlen(buf) - 1] == '/')
- X buf[strlen(buf) - 1] = '\0';
- X if (strlen(buf) + strlen(filename) + 2 > MAXPATHLEN) {
- X set_error(ENAMETOOLONG);
- X strncat(buf, "/", MAXPATHLEN - strlen(buf) - 1);
- X strncat(buf, filename, MAXPATHLEN - strlen(buf) - 1);
- X error(buf);
- X *buf = '\0';
- X return buf;
- X }
- X (void) strcat(buf, "/");
- X (void) strcat(buf, filename);
- X return buf;
- X}
- X
- X
- X
- X
- Xyes() {
- X char buf[BUFSIZ];
- X char *val;
- X
- X val = fgets(buf, BUFSIZ, stdin);
- X if (! val) {
- X printf("\n");
- X exit(1);
- X }
- X if (! index(buf, '\n')) do
- X (void) fgets(buf + 1, BUFSIZ - 1, stdin);
- X while (! index(buf + 1, '\n'));
- X return(*buf == 'y');
- X}
- X
- X
- X
- X
- Xchar *lastpart(filename)
- Xchar *filename;
- X{
- X char *part;
- X
- X part = rindex(filename, '/');
- X
- X if (! part)
- X part = filename;
- X else if (part == filename)
- X part++;
- X else if (part - filename + 1 == strlen(filename)) {
- X part = rindex(--part, '/');
- X if (! part)
- X part = filename;
- X else
- X part++;
- X }
- X else
- X part++;
- X
- X return(part);
- X}
- X
- X
- X
- X
- Xchar *firstpart(filename, rest)
- Xchar *filename;
- Xchar *rest; /* RETURN */
- X{
- X char *part;
- X static char buf[MAXPATHLEN];
- X
- X (void) strcpy(buf, filename);
- X part = index(buf, '/');
- X if (! part) {
- X *rest = '\0';
- X return(buf);
- X }
- X (void) strcpy(rest, part + 1);
- X *part = '\0';
- X return(buf);
- X}
- X
- X
- X
- X
- X
- Xget_home(buf)
- Xchar *buf;
- X{
- X char *user;
- X struct passwd *psw;
- X
- X (void) strcpy(buf, getenv("HOME"));
- X
- X if (*buf)
- X return(0);
- X
- X user = getenv("USER");
- X psw = getpwnam(user);
- X
- X if (psw) {
- X (void) strcpy(buf, psw->pw_dir);
- X return(0);
- X }
- X
- X psw = getpwuid((int) getuid());
- X
- X if (psw) {
- X (void) strcpy(buf, psw->pw_dir);
- X return(0);
- X }
- X
- X set_error(NO_HOME_DIR);
- X error("get_home");
- X return error_code;
- X}
- X
- X
- X
- X
- Xtimed_out(file_ent, current_time, min_days)
- Xfilerec *file_ent;
- Xtime_t current_time, min_days;
- X{
- X if ((current_time - file_ent->specs.st_mtime) / 86400 >= min_days)
- X return(1);
- X else
- X return(0);
- X}
- X
- X
- X
- Xint directory_exists(dirname)
- Xchar *dirname;
- X{
- X struct stat stat_buf;
- X
- X if (stat(dirname, &stat_buf))
- X return(0);
- X else if ((stat_buf.st_mode & S_IFMT) == S_IFDIR)
- X return(1);
- X else
- X return(0);
- X}
- X
- X
- X
- Xis_link(name, oldbuf)
- Xchar *name;
- Xstruct stat *oldbuf;
- X{
- X struct stat statbuf;
- X
- X if (oldbuf)
- X statbuf = *oldbuf;
- X else if (lstat(name, &statbuf) < 0) {
- X set_error(errno);
- X error("is_link");
- X return(0);
- X }
- X
- X if ((statbuf.st_mode & S_IFMT) == S_IFLNK)
- X return 1;
- X else
- X return 0;
- X}
- X
- X
- X
- X/*
- X * This is one of the few procedures that is allowed to break the
- X * rule of always returning an error value if an error occurs. That's
- X * because it's stupid to expect a boolean function to do that, and
- X * because defaulting to not being a mountpoint if there is an error
- X * is a reasonable thing to do.
- X */
- X/*
- X * The second parameter is optional -- if it is non-NULL< it is
- X * presumed to be a stat structure fo the file being passed in.
- X */
- Xint is_mountpoint(name, oldbuf)
- Xchar *name;
- Xstruct stat *oldbuf;
- X{
- X struct stat statbuf;
- X dev_t device;
- X char buf[MAXPATHLEN];
- X#ifdef AFS_MOUNTPOINTS
- X struct ViceIoctl blob;
- X char retbuf[MAXPATHLEN];
- X int retval;
- X char *shortname;
- X#endif
- X
- X /* First way to check for a mount point -- if the device number */
- X /* of name is different from the device number of name/.. */
- X if (oldbuf)
- X statbuf = *oldbuf;
- X else if (lstat(name, &statbuf) < 0) {
- X set_error(errno);
- X error(name);
- X return 0;
- X }
- X
- X device = statbuf.st_dev;
- X
- X if (strlen(name) + 4 /* length of "/.." + a NULL */ > MAXPATHLEN) {
- X set_error(ENAMETOOLONG);
- X error(name);
- X return 0;
- X }
- X
- X strcpy(buf, name);
- X strcat(buf, "/..");
- X if (lstat(buf, &statbuf) < 0) {
- X set_error(errno);
- X error(name);
- X return 0;
- X }
- X
- X if (statbuf.st_dev != device)
- X return 1;
- X
- X#ifdef AFS_MOUNTPOINTS
- X /* Check for AFS mountpoint using the AFS pioctl call. */
- X if ((shortname = lastpart(name)) == name) {
- X strcpy(buf, ".");
- X blob.in = name;
- X blob.in_size = strlen(name) + 1;
- X blob.out = retbuf;
- X blob.out_size = MAXPATHLEN;
- X bzero(retbuf, MAXPATHLEN);
- X }
- X else {
- X strncpy(buf, name, shortname - name - 1);
- X buf[shortname - name - 1] = '\0';
- X if (*buf == '\0')
- X strcpy(buf, "/");
- X blob.in = shortname;
- X blob.in_size = strlen(shortname) + 1;
- X blob.out = retbuf;
- X blob.out_size = MAXPATHLEN;
- X bzero(retbuf, MAXPATHLEN);
- X }
- X
- X retval = pioctl(buf, VIOC_AFS_STAT_MT_PT, &blob, 0);
- X
- X if (retval == 0) {
- X#ifdef DEBUG
- X printf("%s is an AFS mountpoint, is_mountpoint returning true.\n",
- X name);
- X#endif
- X return 1;
- X }
- X else {
- X if (errno != EINVAL) {
- X set_error(errno);
- X error(name);
- X }
- X }
- X#endif /* AFS_MOUNTPOINTS */
- X
- X return 0;
- X}
- X
- X#ifdef MALLOC_DEBUG
- Xchar *Malloc(size)
- Xunsigned size;
- X{
- X extern char *malloc();
- X
- X static int count = 0;
- X char buf[10];
- X
- X count++;
- X
- X fprintf(stderr, "This is call number %d to Malloc, for %u bytes.\n",
- X count, size);
- X fprintf(stdout, "Shall I return NULL for this malloc? ");
- X fgets(buf, 10, stdin);
- X if ((*buf == 'y') || (*buf == 'Y')) {
- X errno = ENOMEM;
- X return ((char *) NULL);
- X }
- X else
- X return (malloc(size));
- X}
- X#endif
- X
- X
- END_OF_FILE
- if test 7849 -ne `wc -c <'util.c'`; then
- echo shar: \"'util.c'\" unpacked with wrong size!
- fi
- # end of 'util.c'
- fi
- echo shar: End of archive 2 \(of 3\).
- cp /dev/null ark2isdone
- MISSING=""
- for I in 1 2 3 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 3 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- exit 0 # Just in case...
-